﻿using Guoc.BigMall.Infrastructure.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Guoc.BigMall.WebService.Implement
{
    public class TokenService : ITokenService
    {
        /// <summary>
        ///  token 当前用户
        /// </summary>
        public string CurrentUserKey
        {
            get { return "current-user"; }
        }
        public string CreateToken(Dictionary<string, string> data, int ExpireMinute = 30)
        {
            var first = Guid.NewGuid().ToString().Replace("-", "");
            data.Add("exp", ToUnixTimeStamp(DateTime.Now.AddMinutes(ExpireMinute)).ToString());
            var payloadString = data.SerializeObject();
            // base 64加密        
            var secondString = Convert.ToBase64String(Encoding.UTF8.GetBytes(payloadString));
            return string.Format("{0}.{1}", first, secondString);
        }

        public Dictionary<string, string> GetData(string token)
        {
            Dictionary<string, string> data = new Dictionary<string, string>();
            if (string.IsNullOrEmpty(token)) { return data; }
            var dataArray = token.Split('.');
            if (dataArray.Length < 2) { return data; }
            var userString = Encoding.UTF8.GetString(Convert.FromBase64String(dataArray[1]));
            data= userString.DeserializeObject<Dictionary<string, string>>();
            return data;
        }

        public bool Validate(string token)
        {
            if (string.IsNullOrEmpty(token)) { return false; }
            Dictionary<string, string> data = GetData(token);
            if (!data.ContainsKey("exp")) { return false; }
            var timeStamp = long.Parse(data["exp"]);
            DateTime expDate = FromUnixTimeStamp(timeStamp);
            TimeSpan ts = expDate - DateTime.Now;
            return ts.TotalSeconds > 60;        //  大于60秒，token 有效，可用，小于60秒 不可用，需要续约

        }

        /// <summary>
        /// 获取时间戳 unix 时间戳,毫秒单位
        /// </summary>
        /// <returns></returns>
        private long ToUnixTimeStamp(DateTime now)
        {
            TimeSpan ts = now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds);
        }

        private DateTime FromUnixTimeStamp(long timestamp)
        {
            DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, 0);
            DateTime dt = start.AddSeconds(timestamp);
            return dt;
        }
    }
}
